const api = require('express').Router()
let { pool, escape } = require('../sql/index.js')
const jwt = require('jsonwebtoken')
const moment = require('moment')
//引入定时执行模块
const schedule = require('node-schedule')
//导入网易云接口
////////获取二维码key  获取二维码地址    二维码扫码状态    签到          个人信息       获取推荐歌单       歌单详情     听歌打卡    云贝签到     获取个人信息  获取歌曲  评论歌曲  分享资源到动态 删除动态      音乐人签到          领取云豆               音乐人任务   获取评论
const { login_qr_key, login_qr_create, login_qr_check, daily_signin, user_account, personalized, playlist_detail, scrobble, yunbei_sign, user_detail, artists, comment, share_resource, event_del, musician_sign, musician_cloudbean_obtain, musician_tasks, comment_new } = require('NeteaseCloudMusicApi')
//生成二维码key
api.post('/api/key', async (req, res) => {
    try {
        const key = await login_qr_key()
        res.send({
            code: 1,
            msg: key
        })
    } catch (error) {
        res.send({
            code: 0,
            msg: error
        })
    }
})
//生成二维码url
api.post('/api/createUrl', async (req, res) => {
    const { key } = req.body
    try {
        const url = await login_qr_create({ key, qrimg: true })
        res.send({
            code: 1,
            msg: url
        })
    } catch (error) {
        res.send({
            code: 0,
            msg: error
        })
    }
})
//查询二维码状态
api.post('/api/UrlState', async (req, res) => {
    const { key } = req.body
    try {
        const cookie = await login_qr_check({ key })
        res.send({
            code: 1,
            msg: cookie
        })
    } catch (error) {
        res.send({
            code: 0,
            msg: error
        })
    }
})
//验证用户token并解密查库，成功返回promise失败返回false
function verifyToken(token) {
    try {
        const json = jwt.verify(token, 'jouei')
        return new Promise((resolve, reject) => {
            pool.query({
                sql: `select * from user where name='${json.name}' and password='${json.password}'`
            }, (err, result) => {
                if (err || !result[0]) {
                    resolve(false)
                } else {
                    resolve(result)
                }
            })
        })

    } catch (err) {
        return false
    }
}
//用户登录
api.post('/api/login', (req, res) => {
    //查询账号密码是否存在数据库中
    pool.query({
        sql: `select * from user where name='${req.body.name}' and password='${req.body.password}'`
    }, (err, result) => {
        if (err || !result[0]) {
            res.send({
                code: 02,
                msg: '账号或密码错误'
            })
        } else {
            const { name, password } = req.body
            //验证成功后生成用户token并添加到数据库
            const token = jwt.sign({ name, password }, 'jouei', { expiresIn: 60 * 60 * 24 * 30 })
            pool.query({
                sql: `UPDATE user SET token="${token}" WHERE name="${name}" AND password="${password}"`
            })
            //返回请求成功数据
            res.send({
                code: 1,
                state: 200,
                text: '登录成功',
                token,
                personalInformation: {
                    name: result[0].name,
                    vip: result[0].vip && moment(result[0].vip).add(8, 'hours')
                }
            })

        }
    })
})
//用户注册
api.post('/api/register', (req, res) => {
    //发送验证码和验证验证码在前端，后台只把用户表单插入到数据库
    pool.query({
        sql: `insert into user (name,password) VALUES ('${req.body.name}','${req.body.password}')`
    }, (err, result) => {
        if (!err) {
            res.send({
                code: 0,
                msg: '注册成功！'
            })
        }
    })
})
//用户个人信息
api.post('/api/info', async (req, res) => {
    let email = await verifyToken(req.headers.token)
    if (email) {
        pool.query({
            sql: `select * from clouduser where creator='${email[0].name}'`
        }, (err, result) => {
            if (err) {
                res.send({
                    code: 0,
                    msg: '请求出错'
                })
            } else {
                let online = result.reduce((total, current) => current.online === 1 ? total + 1 : total + 0, 0)
                let line = result.reduce((total, current) => current.online === 0 ? total + 1 : total + 0, 0)
                res.send({
                    code: 1,
                    date: result,
                    total: result.length,
                    online,
                    line
                })
            }

        })
    }
})
//批量添加卡密传入{key:['卡密'],time:'vip时长'}
api.post('/api/addKey', (req, res) => {
    const { key, time } = req.body
    const keys = JSON.parse(key)
    for (let i = 0; i < keys.length; i++) {
        pool.query({
            sql: `insert into code (code,time) VALUES ('${keys[i]}','${time}')`
        }, err => {
            if (err) {
                res.send({
                    code: 0,
                    msg: '添加失败'
                })
            }
        })
        if (i === keys.length - 1) {
            res.send({
                code: 1,
                msg: '添加成功'
            })
        }
    }
})
//用户添加账号
api.post('/api/addAccount', async (req, res) => {
    //解密token判断用户是否登录状态
    let user = await verifyToken(req.headers.token)
    //验证失败响应错误并终止添加
    if (!user[0]) return res.send({ code: 0, msg: '添加异常,请稍后重试' })
    const { key, cookie, name } = req.body
    let time = 0
    //查询数据库判断卡密是否存在和是否被使用过
    pool.query({
        sql: `select * from code where code="${key}" and isUse=0`
    }, (err, result) => {
        if (err || !result[0]) {
            return res.send({
                code: 0,
                msg: '卡密错误'
            })
        } else {
            //从卡密拿到的vip时间和用户的账号添加到数据库
            time = result[0]?.time
            let now = moment().locale('zh-cn').format('YYYY-MM-DD HH:mm:ss');
            let vip = moment(time == '0' ? '9999-12-31' : now).add(time, 'd').format('YYYY-MM-DD HH:mm:ss')
            pool.query({
                sql: `insert into clouduser (creator,account,vip,cookie,online) VALUES ('${user[0].name}','${name}','${vip}','${cookie}',1)`
            }, (err) => {
                //添加成功后把卡密标记为已使用
                pool.query({
                    sql: `UPDATE code SET isUse=1 WHERE code='${key}'`
                })
                //返回用户添加成功
                if (!err) res.send({ code: 1, msg: '添加成功' })
            })
        }
    })
})
//获取账号配置
api.post('/api/configuration', (req, res) => {
    const { account } = req.body
    try {
        pool.query({
            sql: `select * from clouduser where account='${account}'`
        }, (err, result) => {
            res.send(result[0])
        })
    } catch (error) {
        res.send({
            code: 0,
            msg: error
        })
    }
})
//更新账号配置
api.post('/api/updataConfig', (req, res) => {
    const { key, account, value } = req.body
    try {
        pool.query({
            sql: `update clouduser set ${key}=${value} where account='${account}'`
        })
        res.send({
            code: 1,
            msg: "更新成功"
        })
    } catch (error) {
        res.send({
            code: 0,
            msg: '更新失败'
        })
    }
})
//账号续费
api.post('/api/renew', (req, res) => {
    const { key, account } = req.body
    var nowVip = null //用户vip时间
    let time = null
    //拿到用户vip时间
    pool.query({
        sql: `select * from clouduser where account='${account}'`
    }, (err, result) => {
        nowVip = result[0].vip
        if (moment(nowVip).format('YYYY-MM-DD HH:mm:ss') == moment('9999-12-31').format('YYYY-MM-DD HH:mm:ss')) {
            return res.send({
                code: 0,
                msg: '充值失败您的账号已经是永久了'
            })
        } else {
            pool.query({
                sql: `select * from code where code="${key}" and isUse=0`
            }, (err, result) => {
                console.log(result, err)
                if (err || !result[0]) {
                    return res.send({
                        code: 0,
                        msg: '卡密错误'
                    })
                } else {
                    //从卡密拿到的vip时间和用户的账号添加到数据库
                    time = result[0]?.time
                    let vip = moment(time == '0' ? '9999-12-31' : nowVip).add(time, 'd').format('YYYY-MM-DD HH:mm:ss')
                    pool.query({
                        sql: `update clouduser set vip='${vip}' where account="${account}"`
                    }, (err) => {
                        //添加成功后把卡密标记为已使用
                        pool.query({
                            sql: `UPDATE code SET isUse=1 WHERE code='${key}'`
                        })
                        //返回用户添加成功
                        if (!err) res.send({ code: 1, msg: '续费成功' })
                    })
                }
            })
        }
    })

})
//拉取网易云用户日志
api.post('/api/getLog', (req, res) => {
    const { account } = req.body
    try {
        pool.query({
            sql: `select * from log where account="${account}"`
        }, (err, result) => {
            res.send({
                code: 1,
                data: result
            })
        })
    } catch (error) {
        res.send({
            code: 0,
            msg: '日志拉取失败'
        })
    }
})
//拉取用户全部日志
api.post('/api/getAllLog', async (req, res) => {
    let email = await verifyToken(req.headers.token)
    const creator = email[0]?.name
    try {
        pool.query({
            sql: `select * from log where creator="${creator}"`
        }, (err, result) => {
            res.send({
                code: 1,
                data: result
            })
        })
    } catch (error) {
        res.send({
            code: 0,
            msg: '日志拉取失败'
        })
    }
})
//添加日志
function addLog(creator, account, msg) {
    try {
        pool.query({
            sql: `insert into log (creator,account,msg) VALUES ('${creator}','${account}','${msg}')`
        })
    } catch (error) {

    }

}
//签到
async function checkIn(user) {
    if (!user.checkIn) return
    try {
        const res = await yunbei_sign({
            cookie: user.cookie
        })
        if (res.body.code == 200) {
            const date = moment().format('YYYY年MM月DD日 HH:mm:ss')
            addLog(user.creator, user.account, date + '移动端签到成功')
        } else {
            const date = moment().format('YYYY年MM月DD日 HH:mm:ss')
            addLog(user.creator, user.account, date + '移动端重复签到')
        }
    } catch (error) {
        const date = moment().format('YYYY年MM月DD日 HH:mm:ss')
        addLog(user.creator, user.account, date + '移动端签到' + error.body.msg)
    }
    try {
        const res = await daily_signin({
            type: 0,
            cookie: user.cookie
        })
        if (res.body.code == 200) {
            const date = moment().format('YYYY年MM月DD日 HH:mm:ss')
            addLog(user.creator, user.account, date + 'PC端签到成功')
        } else {
            const date = moment().format('YYYY年MM月DD日 HH:mm:ss')
            addLog(user.creator, user.account, date + 'PC端重复签到')
        }
    } catch (error) {
        const date = moment().format('YYYY年MM月DD日 HH:mm:ss')
        addLog(user.creator, user.account, date + 'PC端签到' + error.body.msg)
    }

}
//获取账号信息用来判断用户cookie是否失效
async function verifyCookie(cookie, account) {
    try {
        const json = await user_account({
            cookie
        })
        if (json.body.code == 200) {
            return json.body.account.id
        } else {
            changeState(account, 0)
            return false
        }
    } catch (error) {
        changeState(account, 0)
        return false
    }
}
//更改用户状态
function changeState(account, state) {
    try {
        pool.query({
            sql: `update clouduser set online='${state}' where account="${account}"`
        })
    } catch (error) {

    }
}
//打卡功能
async function fightCard(user) {
    try {
        const list = await personalized({
            cookie: user.cookie
        })
        //所有歌单
        const { result } = list.body
        if (list.body.code !== 200) return '获取歌单失败'
        let music = await Promise.all(result.map(async (item) => (await playlist_detail({ id: item.id })).body.playlist))
        // console.log(music)
        for (const i in music) {
            const id = music[i].id
            const { tracks } = music[i]
            for (const y in tracks) {
                const result = await scrobble({
                    id: tracks[y].id,
                    sourceid: id,
                    time: 120
                })
            }
        }
        const date = moment().format('YYYY年MM月DD日 HH:mm:ss')
        addLog(user.creator, user.account, date + ' 打卡成功')
    } catch (error) {
        const date = moment().format('YYYY年MM月DD日 HH:mm:ss')
        addLog(user.creator, user.account, date + ' 打卡失败，未知错误')
    }

}
//发布主创说 
async function sendComment(user, id) {
    //延迟执行
    const sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay))
    try {
        //从个人信息获取歌手id
        const info = await user_detail({
            cookie: user.cookie,
            uid: id
        })
        const { artistId } = info.body.profile
        if (artistId) {
            //使用歌手id拿到歌手热门歌曲id的第一首
            const sing = await artists({
                id: artistId
            })
            const { id } = sing.body.hotSongs[0]
            for (let i = 0; i < 2; i++) {
                //发送评论
                const comments = await comment({ cookie: user.cookie, t: 1, type: 0, id, content: '这里由机器自动发送' })
                if (comments?.body.code === 200) {
                    //延迟5秒获取id
                    await sleep(5000)
                    //获取评论id
                    const pl = await comment_new({ id, type: 0, pageSize: 1, cookie: user.cookie, sortType: 3 })
                    const { commentId } = pl.body.data.comments[0]
                    //删除评论
                    const delComment = await comment({ cookie: user.cookie, t: 0, type: 0, id, commentId })
                    if (delComment.body.code === 200) {
                        const date = moment().format('YYYY年MM月DD日 HH:mm:ss')
                        addLog(user.creator, user.account, date + `主创说评论第${i + 1}次完成`)
                        return true
                    }
                    //延迟5秒再次执行循环
                    await sleep(5000)
                }
            }

        } else {
            const date = moment().format('YYYY年MM月DD日 HH:mm:ss')
            addLog(user.creator, user.account, date + ' 不是音乐人账号，自动关闭音乐人任务')
            pool.query({
                sql: `update clouduser set musician='${0}' where account="${user.account}"`
            })
            return false
        }
    } catch (error) {
        console.log(error.body.data.dialog)
        const date = moment().format('YYYY年MM月DD日 HH:mm:ss')
        addLog(user.creator, user.account, date + '主创说评论失败')
        return true
    }

}
//分享自己歌曲到动态并评论
async function shareAndComment(user, id) {
    try {
        //从个人信息获取歌手id
        const info = await user_detail({
            cookie: user.cookie,
            uid: id
        })
        const { artistId } = info.body.profile
        if (artistId) {
            //使用歌手id拿到歌手热门歌曲id的第一首
            const sing = await artists({
                id: artistId
            })
            const { id } = sing.body.hotSongs[0]
            //将歌手的热门歌曲发送到动态
            const dynamic = await share_resource({ cookie: user.cookie, id, type: 'song', msg: '这是由服务器自动发送的动态' })
            //拿到发布的动态threadId
            const dynamicId = dynamic.body.event.threadId
            //拿到动态id
            const evId = dynamic.body.id
            //往发布的动态发送评论
            const comments = await comment({ cookie: user.cookie, t: 1, type: 6, threadId: dynamicId, content: '由机器自动发送评论' })
            //删除动态
            const result = await event_del({ cookie: user.cookie, evId })
            console.log(result)
            if (result.body.code === 200) {
                const date = moment().format('YYYY年MM月DD日 HH:mm:ss')
                addLog(user.creator, user.account, date + ' 发布动态并评论成功')
            }
        } else {
            const date = moment().format('YYYY年MM月DD日 HH:mm:ss')
            addLog(user.creator, user.account, date + ' 不是音乐人账号，自动关闭音乐人任务')
            pool.query({
                sql: `update clouduser set musician='${0}' where account="${user.account}"`
            })
            return false
        }
    } catch (error) {
        console.log(error)
        const date = moment().format('YYYY年MM月DD日 HH:mm:ss')
        addLog(user.creator, user.account, date + ' 发布动态并评论失败')
    }
}
//音乐人签到
async function musicianSign(user) {
    try {
        const result = await musician_sign({ cookie: user.cookie })
        const date = moment().format('YYYY年MM月DD日 HH:mm:ss')
        if (result.body.code === 200) addLog(user.creator, user.account, date + '音乐人签到成功')
    } catch (error) {
        const date = moment().format('YYYY年MM月DD日 HH:mm:ss')
        if (result.body.code === 200) addLog(user.creator, user.account, date + '音乐人签到失败')
    }
}
//领取云豆
async function musicianCloudbean(user) {
    try {
        //调用音乐人任务
        const musicianTasks = await musician_tasks({ cookie: user.cookie })
        const list = musicianTasks.body.data.list
        let finishList = list.filter((item) => item.status === 100)
        for (let i = 0; i < finishList.length; i++) {
            // console.log(finishList[i].userMissionId)
            const result = await musician_cloudbean_obtain({ cookie: user.cookie, id: finishList[i].userMissionId, period: finishList[i].period })
        }
        const date = moment().format('YYYY年MM月DD日 HH:mm:ss')
        addLog(user.creator, user.account, date + '云豆领取成功')
    } catch (error) {
        const date = moment().format('YYYY年MM月DD日 HH:mm:ss')
        addLog(user.creator, user.account, date + '云豆领取失败')
    }
}
//核心功能
async function core() {
    //得到所有用户
    const user = await getAlluser()
    //遍历所有用户
    for (let i = 0; i < user.length; i++) {
        //查看用户状态是否异常
        if (!user[i].online) continue
        //查看用户cookie是否正常
        const state = await verifyCookie(user[i].cookie, user[i].account)
        if (!state) continue
        //调用签到
        if (user[i].checkIn) await checkIn(user[i])
        //打卡
        if (user[i].fightCard) await fightCard(user[i])
        //音乐人任务
        if (user[i].musician) {
            //获取是否网易云音乐人并且执行主创说
            const musicianState = await sendComment(user[i], state)
            if (!musicianState) continue
            //发布动态并评论
            shareAndComment(user[i], state)
            //音乐人签到
            musicianSign(user[i])
            //领取云豆
            musicianCloudbean(user[i])
        }
    }
}
//获取所有用户
function getAlluser() {
    const json = new Promise((resolve, reject) => {
        try {
            pool.query({
                sql: 'select * from clouduser'
            }, (err, result) => {
                resolve(result)
            })
        } catch (error) {
            return false
        }
    })
    return json
}
//更新账号状态
api.post('/api/updataState', (req, res) => {
    const { cookie, account } = req.body
    try {
        pool.query({
            sql: `update clouduser set online='1',cookie="${cookie}" where account="${account}" `
        }, (err) => {
            res.send({
                code: 1,
                msg: '更新成功'
            })
        })
    } catch (error) {
        res.send({
            code: 0,
            msg: '更新失败，请稍后重试'
        })
    }
})
// core() 
//定时任务 每天凌晨4点执行
schedule.scheduleJob('0 0 4 * * ?', () => {
    core()
})
module.exports = api   